using System;
using System.Drawing;
using System.Drawing.Text;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;


namespace Soyuz5.Utility
{
    public static class Image
    {
        /// <summary>
        /// Set image size and proportionally resize image if required
        /// </summary>
        /// <param name="OriginalImage"></param>
        /// <param name="Width"></param>
        /// <param name="Height"></param>
        /// <returns></returns>
        public static Bitmap ResizeImage(System.Drawing.Image OriginalImage, int Width, int Height)
        {
            Size mySize = new Size(OriginalImage.Width, OriginalImage.Height);
            if (Height > 0 && Width > 0 && (Height < OriginalImage.Height || Width < OriginalImage.Width))
            {
                double saveSizeFactor = (double)Width / (double)Height;
                double origSizeFactor = (double)OriginalImage.Width / (double)OriginalImage.Height;
                if (saveSizeFactor == origSizeFactor)
                {
                    mySize = new Size(Height, Width);
                }
                else if (saveSizeFactor < origSizeFactor)
                {
                    Height = (int)((double)OriginalImage.Height * ((double)Width / (double)OriginalImage.Width));
                    mySize = new Size(Width, Height);
                }
                else if (saveSizeFactor > origSizeFactor)
                {
                    Width = (int)((double)OriginalImage.Width * ((double)Height / (double)OriginalImage.Height));
                    mySize = new Size(Width, Height);
                }
            }
            //resize 
            return new Bitmap(OriginalImage, mySize);
        }

        /// <summary>
        /// Create a text Image
        /// </summary>
        /// <param name="Text"></param>
        /// <param name="FontSize"></param>
        /// <param name="FontFace"></param>
        /// <param name="Width"></param>
        /// <param name="ForegroundColor"></param>
        /// <param name="Bold"></param>
        /// <param name="Italic"></param>
        /// <param name="Center"></param>
        /// <returns></returns>
        public static Bitmap CreateTextImage(string Text, int FontSize, string FontFace, int Width, Color ForegroundColor,
            bool Bold, bool Italic,
            bool Center)
        {

            int intImageWidth = 0;
            int intChars = 1;
            int intLines = 1;
            SizeF sfFontSize = new SizeF(Width, 500);
            Color clFont = ForegroundColor;
            StringFormat sfFont = StringFormat.GenericTypographic;

            // if a width is given change alignment to centre
            if (Center && Width > -1) sfFont.Alignment = StringAlignment.Center;
            else sfFont.Alignment = StringAlignment.Near;

            // find the font in private collection
            FontFamily ffFont = null;
            InstalledFontCollection ifc = new InstalledFontCollection();
            foreach (FontFamily ff in ifc.Families)
            {
                if (ff.Name.ToLower() == FontFace.ToLower())
                {
                    ffFont = ff;
                    break;
                }
            }

            // font variants
            FontStyle fsFont = FontStyle.Regular;
            if (Bold) fsFont = FontStyle.Bold;
            if (Italic) fsFont = FontStyle.Italic;
            if (Bold && Italic) fsFont = FontStyle.Italic | FontStyle.Bold;
            Font fntFont = new Font(ffFont, FontSize, fsFont, GraphicsUnit.Pixel);

            // create bitmap to use for text measurements
            Bitmap bmpImage = new Bitmap(1, 1);
            Graphics gImageFontSize = Graphics.FromImage(bmpImage);
            // measure the width the text will be
            if (Width == -1) sfFontSize = gImageFontSize.MeasureString(Text, fntFont, new PointF(0, 0), sfFont);
            else sfFontSize = gImageFontSize.MeasureString(Text, fntFont, sfFontSize, sfFont, out intChars, out intLines);
            intImageWidth = (int)sfFontSize.Width;

            // check if the width is set, if there is no text width and no defined width the width be zero and cause an error
            // also check if intLines == 0, this occurs when there is no text entered.
            if ((Width == -1 && intImageWidth == 0) || intLines == 0) return null;

            // create image
            bmpImage.Dispose();
            bmpImage = new Bitmap((Width == -1 ? intImageWidth : Width) + (Italic ? 10 : 0), fntFont.Height * (intLines), PixelFormat.Format24bppRgb);

            // clear the image to transparent
            bmpImage.MakeTransparent(bmpImage.GetPixel(1, 1));

            // create graphics object from image
            Graphics gImage = Graphics.FromImage(bmpImage);

            // render image properties
            gImage.InterpolationMode = InterpolationMode.HighQualityBicubic;
            gImage.TextRenderingHint = TextRenderingHint.AntiAlias;

            // if set width then flow text onto new lines
            if (Width == -1)
            {
                gImage.DrawString(Text, fntFont, new SolidBrush(clFont), 0, 0, sfFont);
            }
            else
            {
                gImage.DrawString(Text, fntFont, new SolidBrush(clFont), new RectangleF(0, 0, Width, 1000), sfFont);
            }

            gImage.Flush();
            return bmpImage;
        }

        /// <summary>
        /// Add a second image as a watermark to the first
        /// </summary>
        /// <param name="Image"></param>
        /// <param name="WaterMark"></param>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <param name="Opacity"></param>
        /// <returns></returns>
        public static bool AddWaterMark(Bitmap Image, Bitmap WaterMark, int X, int Y, float Opacity)
        {

            // Add transformation matrix
            float flTransparentLevel = Opacity;
            ImageAttributes imageAttributes = new ImageAttributes();
            float[][] colorMatrixElements = { 
												new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
												new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
												new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
												new float[] {0.0f,  0.0f,  0.0f,  flTransparentLevel, 0.0f},
												new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
											};

            ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
            imageAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

            // Match the resolution
            WaterMark.SetResolution(Image.HorizontalResolution, Image.VerticalResolution);

            // Apply image using transformation
            Graphics grWatermark = Graphics.FromImage(Image);

            grWatermark.DrawImage(WaterMark,
                new Rectangle(X, Y, WaterMark.Width, WaterMark.Height), 0, 0,
                WaterMark.Width, WaterMark.Height, GraphicsUnit.Pixel, imageAttributes);
            grWatermark.Dispose();

            return true;
        }

    }
}
